﻿using System;
using System.Threading;

namespace MyLib 
{
    public static class SynchroniztionContextExtensions
    {
        /// <summary>
        /// 扩展方法
        /// 1:SyncContext 可以创建Task
        /// 2:Task 共享SyncContext 执行代码的时候 GetAwaiter 到 Awaiter中
        /// 3:线程局部变量ThreadStatic 
        /// 4:Task和某个 SyncContext 绑定
        /// 5：Actor--》对应一个SyncContext
        /// 6：RunTask 将Task在Actor对应的Context中执行 ActorSynchronizationContext
        /// 7：WorkerThread 调度Task到对应SyncContext去执行 Context在某个线程上执行
        /// 8：不支持Send同步执行，只支持Post 异步调用
        /// 9：执行Task时，设置当前线程的Context为该Actor的Context 
        /// 10：如果当前有任务在执行Actor上，则新任务加入到Queue中
        /// 11：当Actor上的当前任务执行完成，在其当前线程上，继续执行Queue中的Task
        /// 12：Consume可能会一直占用某个线程
        /// 
        /// 13:当Task 创建的时候，会使用当前线程的SyncContext, Actor中RunTask 和 Async方法中 await mq, 之后就会切换线程上下文到Actor上下文
        /// 14:创建的Task调度器，由当前的SynContext 对应的调度器
        /// https://referencesource.microsoft.com/#mscorlib/system/threading/tasks/TaskScheduler.cs.html
        /// 如何避免每次都创建新的调度器 RunTask
        /// await Task.Delay() 如何
        /// 
        /// TaskScheduler 获取当前TaskScheduler 多个调度器
        /// https://referencesource.microsoft.com/#mscorlib/system/threading/tasks/TaskScheduler.cs,495c69a13f3b023f
        /// 默认的调度器
        /// new ThreadPoolTaskScheduler(); 创建线程池 
        /// Thread 可以Start Task执行某个Task
        /// ThreadPool  调度执行Task
        /// 可以创建单独的线程，添加对应的Context来执行对应的长期运行Task
        /// Context会导致就在当前线程下执行 网络IO线程 无法确保每个Context有单独的线程池
        ///  Thread thread = new Thread(s_longRunningThreadWork);
        /// thread.IsBackground = true; // Keep this thread from blocking process shutdown
        ///        thread.Start(task); 启动线程执行某个Room 当Room空闲的时候
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static SynchronizationContextAwaiter GetAwaiter (this SynchronizationContext context) 
        {
            if(context == null) throw new ArgumentNullException("context");
            return new SynchronizationContextAwaiter(context);
        }
    }
}

